namespace ContractAssertion
{
	using System;
	using System.Collections.Generic;
	using Microsoft.VisualStudio.TestTools.UnitTesting;
	using DependencyLib;
	using CrossFlow.GraphLib;

	[TestClass]
	public class Digraph
	{
		DirectedGraph TheGraph;

		[TestInitialize]
		public void Setup()
		{
			IDependencyProvider provider = new MockDependencyProvider("digraph0");
			MockDependencyProvider depends = provider as MockDependencyProvider;
			depends.VertexNames.Add("v0");
			depends.VertexNames.Add("v1");
			depends.VertexNames.Add("v2");
			depends.EdgePairs.Add(new KeyValuePair<string, string>("v0", "v1"));
			depends.EdgePairs.Add(new KeyValuePair<string, string>("v0", "v2"));
			depends.EdgePairs.Add(new KeyValuePair<string, string>("v1", "v2"));
			depends.EdgePairs.Add(new KeyValuePair<string, string>("v2", "v1"));
			depends.EdgeNodes.Add(new MockDependencyProvider.EdgeInfo("e", "v1", "v0", 123));
			TheGraph = provider.CreateGraph();
		}

		[TestMethod]
		public void Traversal_ForwardOnly()
		{
			DirectedGraph graph = TheGraph;
			Assert.AreEqual<string>("v0", graph.InitialVertex.Name);
			int name_count = 0;
			foreach (Vertex v in graph.Vertexes) ++name_count;
			Assert.AreEqual<int>(3, name_count);
			name_count = 0;
			foreach (Edge e in graph.Edges)
			{
				Assert.IsNotNull(e.Source);
				Assert.IsNotNull(e.Target);
				++name_count;
			}
			Assert.AreEqual<int>(5, name_count);
		}

		[TestMethod]
		public void VertexProperties()
		{
			DirectedGraph graph = TheGraph;
			Vertex root = graph.InitialVertex;
			Assert.AreEqual<string>("v0", root.Name);
			Assert.AreEqual<int>(3, root.EdgeCount);
			Assert.AreEqual<int>(2, root.OutgoingEdgeCount);
			Assert.AreEqual<int>(1, root.IncomingEdgeCount);
			Assert.IsFalse(root.IsComposite);

			Vertex none = root["none"];
			Assert.IsNull(none);

			Vertex v2 = root["v2"];
			Assert.IsNotNull(v2);
			Assert.AreEqual<string>("v2", v2.Name);

			IEnumerator<Edge> iterator = root.Edges.GetEnumerator();
			Assert.IsTrue(iterator.MoveNext());
			Edge e = iterator.Current;
			Assert.AreSame(root, e.Source);
			Assert.AreEqual<string>("v1", e.Target.Name);
			Assert.IsTrue(iterator.MoveNext());
			Assert.AreSame(v2, iterator.Current.Target);
			Assert.AreEqual<int>(2, iterator.Current.Target.IncomingEdgeCount);
		}

		[TestMethod]
		public void ArcProperties()
		{
			DirectedGraph graph = TheGraph;
			Vertex root = graph.InitialVertex;
			Assert.AreEqual<int>(1, root.IncomingEdgeCount);
			Assert.AreEqual<int>(2, root.OutgoingEdgeCount);
			Assert.AreEqual<int>(3, root.EdgeCount);

			int nonames = 0;
			int names = 0;
			foreach (Edge e in root.Edges)
			{
				if (string.IsNullOrEmpty(e.Name)) ++nonames;
				else
				{
					++names;
					if(e.Name.Length==1)
						Assert.AreEqual<string>("e", e.Name);
				}
			}
			Assert.AreEqual<int>(0, nonames);
			Assert.AreEqual<int>(3, names);
		}

		[TestMethod, Ignore]
		public void AsPathTraverse_Basic()
		{
			//it is not clear yet, where the traversal design wants to go
			Assert.Fail();
		}
	}
}